package org.myOrg.spetrum.spectrumStruct;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.myOrg.spetrum.combination.Tuple;
import org.myOrg.spetrum.combination.TupleCase;
import org.myOrg.spetrum.combination.TupleCaseImplement;
import org.myOrg.spetrum.testObject.TestCase;
import org.myOrg.spetrum.testObject.TestSuite;
import org.myOrg.spetrum.testObject.TestSuiteImplement;
import org.myOrg.spetrum.testRun.TestRun;

@Deprecated
public class SpectrumAnalyseImplment implements SpectrumAnalyse {

	private HashSet<Tuple> wrongTuples;
	private HashSet<Tuple> rightTuples;
	private HashSet<Tuple> bugModel;

	private TestSuite rightTestCases;
	private TestSuite wrongTestCases;
	private int[] param;

	/**
	 * @param param the param to set
	 */
	public void setParam(int[] param) {
		this.param = param;
	}
	public int[] getParam(){
		return param;
	}

	private TestSuite generateTestCases;

	private TestRun run;

	public SpectrumAnalyseImplment(TestRun run, TestSuite wrongTestCases,
			TestSuite rightTestCases) {
		this.init();
		this.run = run;
		this.rightTestCases = rightTestCases;
		this.wrongTestCases = wrongTestCases;
	}

	public SpectrumAnalyseImplment() {
		init();
	}
	public void init(){
		generateTestCases = new TestSuiteImplement();
		wrongTuples = new HashSet<Tuple>();
		rightTuples = new HashSet<Tuple>();
		bugModel = new HashSet<Tuple>();
	}
	/**
	 * @param rightTestCases
	 *            the rightTestCases to set
	 */
	public void setRightTestCases(TestSuite rightTestCases) {
		this.rightTestCases = rightTestCases;
	}

	/**
	 * @param wrongTestCases
	 *            the wrongTestCases to set
	 */
	public void setWrongTestCases(TestSuite wrongTestCases) {
		this.wrongTestCases = wrongTestCases;
	}

	/**
	 * @param run
	 *            the run to set
	 */
	public void setRun(TestRun run) {
		this.run = run;
	}

	@Override
	public void clear() {
		// TODO Auto-generated method stub
		generateTestCases.clear();
		wrongTuples.clear();
		rightTuples.clear();
		bugModel.clear();
	}

	@Override
	public boolean isTupleAnalysed(Tuple tuple) {
		// TODO Auto-generated method stub
		if (wrongTuples.contains(tuple) || rightTuples.contains(tuple))
			return true;
		else
			return false;
	}

	@Override
	public boolean isTupleAppearInRightTestCases(Tuple tuple) {
		// TODO Auto-generated method stub
		for(int i = 0 ; i < rightTestCases.getTestCaseNum(); i++){
			if(rightTestCases.getAt(i).containsOf(tuple))
				return true;
		}
		return false;
	}

	@Override
	public boolean isTupleHasKownedBugModel(Tuple tuple) {
		// TODO Auto-generated method stub
		Iterator<Tuple> itr = bugModel.iterator();
		while (itr.hasNext()) {
			if (tuple.contains(itr.next()))
				return true;
		}
		return false;
	}

	@Override
	public boolean isTupleRightOrWrong(Tuple tuple) {
		// TODO Auto-generated method stub
		return rightTuples.contains(tuple);
	}

	/**
	 * @return the bugModel
	 */
	public HashSet<Tuple> getBugModel() {
		return bugModel;
	}

	/**
	 * @return the generateTestCases
	 */
	@Override
	public TestSuite getGenerateTestCases() {
		return generateTestCases;
	}

	@Override
	public boolean isTupleTheBugModel(Tuple tuple) {
		// TODO Auto-generated method stub
		return this.bugModel.contains(tuple);
	}

	@Override
	public void setTupleBugModel(Tuple tuple) {
		// TODO Auto-generated method stub
		this.bugModel.add(tuple);
	}

	/**
	 * set the tuple and its child or grandchild true or false
	 */
	@Override
	public void setTupleRightOrWrong(Tuple tuple, boolean rightOrWrong) {
		// TODO Auto-generated method stub
		if (rightOrWrong == true) {
			this.rightTuples.add(tuple);
		} else
			this.wrongTuples.add(tuple);
	}

	@Override
	public TestCase generateOneRightTestCase() {
		// TODO Auto-generated method stub
		if (this.rightTestCases.getTestCaseNum() != 0)
			return this.rightTestCases.getAt(0);
		else
			return null;
	}

	@Override
	public boolean analyseTuple(Tuple tuple) {
		// TODO Auto-generated method stub
		if (isTupleAnalysed(tuple))
			return isTupleRightOrWrong(tuple);

		if (isTupleAppearInRightTestCases(tuple)) {
			iteratorSetRightTuple(tuple);
			return true;
		}

		if (isTupleHasKownedBugModel(tuple)) {
			setTupleRightOrWrong(tuple, false);
			iteratorChildAnalyse(tuple);
			return false;
		} else {
			return generateTestCaseToJudge(tuple);
		}

	}

	private void iteratorSetRightTuple(Tuple tuple) {
		setTupleRightOrWrong(tuple, true);
		Iterator<Tuple> itr = tuple.getChildTuples().iterator();
		while (itr.hasNext()) {
			iteratorSetRightTuple(itr.next());
		}
	}

	public boolean generateTestCaseToJudge(Tuple tuple) {
		TupleCase tupleCase = new TupleCaseImplement();
		TestCase testCase = tupleCase.getCaseFromTuple(tuple,
				generateOneRightTestCase());

		run.runTestCase(testCase);
		generateTestCases.addTest(testCase);

		if (testCase.testDescription() == TestCase.PASSED) {
			setTupleRightOrWrong(tuple, true);
			return true;
		} else {
			setTupleRightOrWrong(tuple, false);
			if (iteratorChildAnalyse(tuple))
				setTupleBugModel(tuple);
			return false;
		}
	}

	protected boolean iteratorChildAnalyse(Tuple tuple) {
		List<Tuple> childs = tuple.getChildTuples();
		Iterator<Tuple> itr = childs.iterator();
		boolean result = true;
		while (itr.hasNext()) {
			result &= analyseTuple(itr.next());
		}
		return result;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub	
		for(int i = 0; i < wrongTestCases.getTestCaseNum(); i++){
			analyseOneTestCase(wrongTestCases.getAt(i));
		}
	}

	private void analyseOneTestCase(TestCase  wrongCase) {
		TupleCase tupleCase = new TupleCaseImplement();
		int degree = wrongCase.getLength() < SpectrumAnalyse.MAXDEGREE ? wrongCase
				.getLength() : SpectrumAnalyse.MAXDEGREE;
		List<Tuple> tuples = tupleCase.getTuplesFromCase(wrongCase, degree);
		Iterator<Tuple> itrTuple = tuples.iterator();
		while(itrTuple.hasNext()){
			analyseTuple(itrTuple.next());
		}
	}

}
